/*
 * Copyright (C) 2011, EADS France
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 */

package xowl.interpreter.impl;

import xowl.utils.Values;
import xowl.interpreter.QuerySolution;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import xowl.interpreter.Repository;
import xowl.interpreter.XOWLException;
import xowl.lang.actions.ArrayElement;
import xowl.lang.actions.BAnd;
import xowl.lang.actions.BNot;
import xowl.lang.actions.BOr;
import xowl.lang.actions.BXOr;
import xowl.lang.actions.CodeVariable;
import xowl.lang.actions.Concat;
import xowl.lang.actions.Different;
import xowl.lang.actions.Divide;
import xowl.lang.actions.EntityForIRI;
import xowl.lang.actions.Equal;
import xowl.lang.actions.Greater;
import xowl.lang.actions.GreaterEqual;
import xowl.lang.actions.IRIOf;
import xowl.lang.actions.Invoke;
import xowl.lang.actions.Execute;
import xowl.lang.actions.LengthOf;
import xowl.lang.actions.Lesser;
import xowl.lang.actions.LesserEqual;
import xowl.lang.actions.Minus;
import xowl.lang.actions.Modulus;
import xowl.lang.actions.Mult;
import xowl.lang.actions.NewEntity;
import xowl.lang.actions.NewIndividual;
import xowl.lang.actions.Plus;
import xowl.lang.actions.QueryVariable;
import xowl.lang.actions.Slice;
import xowl.lang.interop.JavaInvokation;
import xowl.lang.interop.NewObject;
import xowl.lang.interop.ObjectField;
import xowl.lang.interop.StaticField;
import xowl.lang.owl2.AnonymousIndividual;
import xowl.lang.owl2.DataAllValuesFrom;
import xowl.lang.owl2.DataComplementOf;
import xowl.lang.owl2.DataExactCardinality;
import xowl.lang.owl2.DataHasValue;
import xowl.lang.owl2.DataIntersectionOf;
import xowl.lang.owl2.DataMaxCardinality;
import xowl.lang.owl2.DataMinCardinality;
import xowl.lang.owl2.DataOneOf;
import xowl.lang.owl2.DataSomeValuesFrom;
import xowl.lang.owl2.DataUnionOf;
import xowl.lang.owl2.DatatypeRestriction;
import xowl.lang.owl2.IRI;
import xowl.lang.owl2.ObjectAllValuesFrom;
import xowl.lang.owl2.ObjectComplementOf;
import xowl.lang.owl2.ObjectExactCardinality;
import xowl.lang.owl2.ObjectHasSelf;
import xowl.lang.owl2.ObjectHasValue;
import xowl.lang.owl2.ObjectIntersectionOf;
import xowl.lang.owl2.ObjectInverseOf;
import xowl.lang.owl2.ObjectMaxCardinality;
import xowl.lang.owl2.ObjectMinCardinality;
import xowl.lang.owl2.ObjectOneOf;
import xowl.lang.owl2.ObjectSomeValuesFrom;
import xowl.lang.owl2.ObjectUnionOf;
import xowl.lang.runtime.Array;
import xowl.lang.runtime.Class;
import xowl.lang.runtime.DataProperty;
import xowl.lang.runtime.Datatype;
import xowl.lang.runtime.Entity;
import xowl.lang.runtime.Function;
import xowl.lang.runtime.Individual;
import xowl.lang.runtime.JavaObject;
import xowl.lang.runtime.Literal;
import xowl.lang.runtime.ObjectProperty;
import xowl.lang.runtime.Value;

/**
 *
 * @author Laurent WOUTERS
 */
public abstract class QueryEvaluator extends AbstractEvaluator {
    @Override public boolean can(xowl.lang.owl2.Expression exp) { return (exp instanceof xowl.lang.actions.Query); }
    @Override public boolean can(xowl.lang.actions.Query exp) { return true; }
	
    @Override protected Value eval_Invoke(Evaluator parent, Invoke expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Value eval_Execute(Evaluator parent, Execute expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Value eval_QueryVariable(Evaluator parent, QueryVariable expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Value eval_CodeVariable(Evaluator parent, CodeVariable expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Value eval_ArrayElement(Evaluator parent, ArrayElement expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Entity eval_Entity(Evaluator parent, IRI expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Entity eval_NewEntity(Evaluator parent, NewEntity expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Entity eval_EntityForIRI(Evaluator parent, EntityForIRI expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Class eval_Class(Evaluator parent, IRI expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Class eval_ObjectUnionOf(Evaluator parent, ObjectUnionOf expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Class eval_ObjectIntersectionOf(Evaluator parent, ObjectIntersectionOf expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Class eval_ObjectOneOf(Evaluator parent, ObjectOneOf expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Class eval_ObjectComplementOf(Evaluator parent, ObjectComplementOf expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Class eval_DataAllValuesFrom(Evaluator parent, DataAllValuesFrom expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Class eval_DataExactCardinality(Evaluator parent, DataExactCardinality expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Class eval_DataHasValue(Evaluator parent, DataHasValue expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Class eval_DataMaxCardinality(Evaluator parent, DataMaxCardinality expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Class eval_DataMinCardinality(Evaluator parent, DataMinCardinality expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Class eval_DataSomeValuesFrom(Evaluator parent, DataSomeValuesFrom expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Class eval_ObjectAllValuesFrom(Evaluator parent, ObjectAllValuesFrom expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Class eval_ObjectExactCardinality(Evaluator parent, ObjectExactCardinality expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Class eval_ObjectHasSelf(Evaluator parent, ObjectHasSelf expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Class eval_ObjectHasValue(Evaluator parent, ObjectHasValue expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Class eval_ObjectMaxCardinality(Evaluator parent, ObjectMaxCardinality expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Class eval_ObjectMinCardinality(Evaluator parent, ObjectMinCardinality expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Class eval_ObjectSomeValuesFrom(Evaluator parent, ObjectSomeValuesFrom expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected ObjectProperty eval_ObjectProperty(Evaluator parent, IRI expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected ObjectProperty eval_ObjectInverseOf(Evaluator parent, ObjectInverseOf expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected DataProperty eval_DataProperty(Evaluator parent, IRI expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Datatype eval_Datatype(Evaluator parent, IRI expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Datatype eval_DataComplementOf(Evaluator parent, DataComplementOf expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Datatype eval_DataIntersectionOf(Evaluator parent, DataIntersectionOf expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Datatype eval_DataOneOf(Evaluator parent, DataOneOf expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Datatype eval_DatatypeRestriction(Evaluator parent, DatatypeRestriction expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Datatype eval_DataUnionOf(Evaluator parent, DataUnionOf expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Individual eval_NamedIndividual(Evaluator parent, IRI expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Individual eval_AnonymousIndividual(Evaluator parent, AnonymousIndividual expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Individual eval_NewIndividual(Evaluator parent, NewIndividual expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Literal eval_Literal(Evaluator parent, xowl.lang.owl2.Literal expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Literal eval_Plus(Evaluator parent, Plus expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Literal eval_Minus(Evaluator parent, Minus expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Literal eval_Mult(Evaluator parent, Mult expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Literal eval_Divide(Evaluator parent, Divide expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Literal eval_Modulus(Evaluator parent, Modulus expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Literal eval_BAnd(Evaluator parent, BAnd expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Literal eval_BOr(Evaluator parent, BOr expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Literal eval_BXOr(Evaluator parent, BXOr expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Literal eval_BNot(Evaluator parent, BNot expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Literal eval_Equal(Evaluator parent, Equal expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Literal eval_Different(Evaluator parent, Different expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Literal eval_Greater(Evaluator parent, Greater expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Literal eval_GreaterEqual(Evaluator parent, GreaterEqual expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Literal eval_Lesser(Evaluator parent, Lesser expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Literal eval_LesserEqual(Evaluator parent, LesserEqual expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Literal eval_IRIOf(Evaluator parent, IRIOf expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Literal eval_LengthOf(Evaluator parent, LengthOf expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Function eval_Function(Evaluator parent, IRI expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Array eval_Array(Evaluator parent, xowl.lang.actions.Array expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Array eval_Concat(Evaluator parent, Concat expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected Array eval_Slice(Evaluator parent, Slice expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected JavaObject eval_JavaInvokation(Evaluator parent, JavaInvokation expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected JavaObject eval_NewObject(Evaluator parent, NewObject expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected JavaObject eval_ObjectField(Evaluator parent, ObjectField expression) throws XOWLException { throw getNotImplemented(); }
    @Override protected JavaObject eval_StaticField(Evaluator parent, StaticField expression) throws XOWLException { throw getNotImplemented(); }
    
    protected List<QuerySolution> select_FunctionDefinition(Evaluator evaluator, Repository repository, xowl.lang.actions.FunctionDefinition axiom) throws xowl.interpreter.XOWLException {
        List<QuerySolution> result = new ArrayList<QuerySolution>();
        xowl.lang.actions.QueryVariable var = null;
        if (Values.isQueryVar(axiom.getFunction())) {
            var = (xowl.lang.actions.QueryVariable)axiom.getFunction();
            xowl.lang.runtime.Closure closure = this.evalClosure(evaluator, axiom.getBehavior());
            xowl.lang.runtime.Function function = ((BaseRepository)repository).getFunction(closure.getCloses());
            if (function != null)
                result.add(getSingleton(var, function.getInterpretationOf()));
        } else if (Values.isQueryVar(axiom.getBehavior())) {
            xowl.lang.runtime.Function function = evaluator.evalFunction(evaluator, axiom.getFunction());
            var = (xowl.lang.actions.QueryVariable)axiom.getBehavior();
            for (xowl.lang.runtime.Closure closure : function.getAllDefinedAs())
                result.add(getSingleton(var, closure));
        }
        return result;
    }

    protected xowl.lang.runtime.Value contains_FunctionDefinition(Evaluator evaluator, Repository repository, xowl.lang.actions.FunctionDefinition axiom) throws xowl.interpreter.XOWLException {
        xowl.lang.runtime.Function function = evaluator.evalFunction(evaluator, axiom.getFunction());
        xowl.lang.runtime.Closure closure = evaluator.evalClosure(evaluator, axiom.getBehavior());
        for (xowl.lang.runtime.Closure tested : function.getAllDefinedAs()) {
            if (tested.getCloses() == closure.getCloses())
                return Values.getValue(repository, true);
            
        }
        return Values.getValue(repository, false);
    }

    protected QuerySolution getSingleton(xowl.lang.actions.QueryVariable var, xowl.lang.runtime.Value value) {
        Map<xowl.lang.actions.QueryVariable, xowl.lang.runtime.Value> map = new HashMap<xowl.lang.actions.QueryVariable, xowl.lang.runtime.Value>();
        map.put(var, value);
        return new QuerySolution(map);
    }
}
